package handlers

import (
	"fmt"
	"io"
	"mime/multipart"
	"net/http"

	"swift-webdrive/services"

	"github.com/gin-gonic/gin"
)

type WebDriveHandler struct {
	swiftService *services.SwiftService
	config       map[string]interface{}
}

func NewWebDriveHandler(swiftService *services.SwiftService, config map[string]interface{}) *WebDriveHandler {
	return &WebDriveHandler{
		swiftService: swiftService,
		config:       config,
	}
}

func (h *WebDriveHandler) Dashboard(c *gin.Context) {
	user := c.MustGet("user").(*UserContext)
	containerName := c.DefaultQuery("container", "")

	if containerName == "" && len(user.Containers) > 0 {
		containerName = user.Containers[0]
	}

	// 检查用户是否有权限访问此容器
	if !h.hasContainerAccess(user, containerName) {
		containerName = user.Containers[0]
	}

	// 获取容器列表
	containers, err := h.swiftService.ListContainers()
	if err != nil {
		c.HTML(http.StatusInternalServerError, "webdrive.html", gin.H{
			"error": "获取容器列表失败: " + err.Error(),
			"user":  user,
		})
		return
	}

	// 过滤用户可访问的容器
	userContainers := h.filterUserContainers(containers, user)

	// 获取对象列表
	var objects []services.ObjectInfo
	if containerName != "" {
		objects, err = h.swiftService.ListObjects(containerName)
		if err != nil {
			c.HTML(http.StatusInternalServerError, "webdrive.html", gin.H{
				"error": "获取文件列表失败: " + err.Error(),
				"user":  user,
			})
			return
		}
	}

	c.HTML(http.StatusOK, "webdrive.html", gin.H{
		"title":             "企业文档存储系统",
		"user":              user,
		"containers":        userContainers,
		"current_container": containerName,
		"objects":           objects,
		"upload_enabled":    h.hasPermission(user, "write"),
		"delete_enabled":    h.hasPermission(user, "delete"),
	})
}

func (h *WebDriveHandler) UploadFile(c *gin.Context) {
	user := c.MustGet("user").(*UserContext)

	if !h.hasPermission(user, "write") {
		c.JSON(http.StatusForbidden, gin.H{"error": "没有上传权限"})
		return
	}

	containerName := c.PostForm("container")
	if !h.hasContainerAccess(user, containerName) {
		c.JSON(http.StatusForbidden, gin.H{"error": "没有访问此容器的权限"})
		return
	}

	// 获取上传的文件
	file, header, err := c.Request.FormFile("file")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "获取上传文件失败"})
		return
	}
	defer file.Close()

	// 检查文件大小和类型
	if err := h.validateFile(header); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 上传到Swift
	contentType := h.getContentType(header.Filename)
	err = h.swiftService.UploadObject(containerName, header.Filename, file, contentType)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "上传失败: " + err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message":   "文件上传成功",
		"filename":  header.Filename,
		"container": containerName,
	})
}

func (h *WebDriveHandler) DownloadFile(c *gin.Context) {
	user := c.MustGet("user").(*UserContext)
	containerName := c.Param("container")
	objectName := c.Param("object")

	if !h.hasContainerAccess(user, containerName) {
		c.JSON(http.StatusForbidden, gin.H{"error": "没有访问此容器的权限"})
		return
	}

	// 获取对象元数据
	metadata, err := h.swiftService.GetObjectMetadata(containerName, objectName)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "文件不存在"})
		return
	}

	// 下载对象
	reader, err := h.swiftService.DownloadObject(containerName, objectName)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "下载失败: " + err.Error()})
		return
	}
	defer reader.Close()

	// 设置响应头
	c.Header("Content-Description", "File Transfer")
	c.Header("Content-Transfer-Encoding", "binary")
	c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", objectName))
	c.Header("Content-Type", metadata["content-type"])
	c.Header("Content-Length", metadata["content-length"])

	// 流式传输文件
	_, err = io.Copy(c.Writer, reader)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "传输失败"})
		return
	}
}

func (h *WebDriveHandler) DeleteFile(c *gin.Context) {
	user := c.MustGet("user").(*UserContext)

	if !h.hasPermission(user, "delete") {
		c.JSON(http.StatusForbidden, gin.H{"error": "没有删除权限"})
		return
	}

	containerName := c.Param("container")
	objectName := c.Param("object")

	if !h.hasContainerAccess(user, containerName) {
		c.JSON(http.StatusForbidden, gin.H{"error": "没有访问此容器的权限"})
		return
	}

	err := h.swiftService.DeleteObject(containerName, objectName)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "删除失败: " + err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message":  "文件删除成功",
		"filename": objectName,
	})
}

func (h *WebDriveHandler) GetObjectInfo(c *gin.Context) {
	user := c.MustGet("user").(*UserContext)
	containerName := c.Param("container")
	objectName := c.Param("object")

	if !h.hasContainerAccess(user, containerName) {
		c.JSON(http.StatusForbidden, gin.H{"error": "没有访问此容器的权限"})
		return
	}

	metadata, err := h.swiftService.GetObjectMetadata(containerName, objectName)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "文件不存在"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"name":      objectName,
		"container": containerName,
		"metadata":  metadata,
	})
}

// 辅助函数
func (h *WebDriveHandler) hasContainerAccess(user *UserContext, containerName string) bool {
	for _, container := range user.Containers {
		if container == containerName {
			return true
		}
	}
	return false
}

func (h *WebDriveHandler) hasPermission(user *UserContext, permission string) bool {
	for _, perm := range user.Permissions {
		if perm == permission {
			return true
		}
	}
	return false
}

func (h *WebDriveHandler) filterUserContainers(containers []services.ContainerInfo, user *UserContext) []services.ContainerInfo {
	var result []services.ContainerInfo
	for _, container := range containers {
		if h.hasContainerAccess(user, container.Name) {
			result = append(result, container)
		}
	}
	return result
}

func (h *WebDriveHandler) validateFile(header *multipart.FileHeader) error {
	// 检查文件大小
	maxSize := h.getMaxFileSize()
	if header.Size > maxSize {
		return fmt.Errorf("文件大小超过限制 (%s)", services.FormatFileSize(maxSize))
	}

	// 检查文件扩展名
	ext := services.GetFileExtension(header.Filename)
	if h.isBlockedExtension(ext) {
		return fmt.Errorf("不允许上传此类型文件: %s", ext)
	}

	if !h.isAllowedExtension(ext) {
		return fmt.Errorf("不支持的文件类型: %s", ext)
	}

	return nil
}

func (h *WebDriveHandler) getMaxFileSize() int64 {
	return 100 * 1024 * 1024
}

func (h *WebDriveHandler) isAllowedExtension(ext string) bool {
	return true
}

func (h *WebDriveHandler) isBlockedExtension(ext string) bool {
	return false
}

func (h *WebDriveHandler) getContentType(filename string) string {
	ext := services.GetFileExtension(filename)

	contentTypes := map[string]string{
		".pdf":  "application/pdf",
		".doc":  "application/msword",
		".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
		".xls":  "application/vnd.ms-excel",
		".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
		".ppt":  "application/vnd.ms-powerpoint",
		".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
		".txt":  "text/plain",
		".jpg":  "image/jpeg",
		".jpeg": "image/jpeg",
		".png":  "image/png",
		".zip":  "application/zip",
	}

	if contentType, exists := contentTypes[ext]; exists {
		return contentType
	}

	return "application/octet-stream"
}
